package service

import (
	"fmt"
	"ginchat/models"
	"ginchat/utils"
	"math/rand/v2"
	"net/http"
	"strconv"
	"time"

	"github.com/asaskevich/govalidator"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

// go get github.com/gorilla/websocket
// go get github.com/asaskevich/govalidator
// go get github.com/gin-gonic/gin

// GetUserList
// @Summary 用户列表
// @Tags 用户模块
// @Produce json
// @Success 200 {string} json{"code", "msg", "data"}
// @Router /users [get]
func GetUserList(ctx *gin.Context) {
	users := make([]*models.UserBasic, 10)
	result := utils.DB.Find(&users)
	if result.Error != nil {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("查找用户失败: %s", result.Error),
		})
		return
	}

	ctx.JSON(200, gin.H{
		"code": 1,
		"msg":  users,
	})
}

// GetUser
// @Summary 查询用户
// @Tags 用户模块
// @Param id path int true "id"
// @Success 200 {string} json{"code", "msg", "data"}
// @Router /user/{id} [get]
func GetUser(ctx *gin.Context) {
	user := models.UserBasic{}
	id, _ := strconv.Atoi(ctx.Param("id"))
	user.ID = uint(id)

	result := utils.DB.First(&user)
	if result.Error != nil {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("查找用户失败: %s", result.Error),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code": 1,
		"data": user,
	})
}

// UserLogin
// @Summary 用户登陆
// @Tags 用户模块
// @Param name formData string false "name"
// @Param password formData string false "password"
// @Success 200 {string} json{"code", "msg", "data"}
// @Router /login [post]
func UserLogin(ctx *gin.Context) {
	user := models.UserBasic{}
	name := ctx.PostForm("name")
	password := ctx.PostForm("password")

	result := utils.DB.Where("name = ?", name).First(&user)
	if result.Error != nil {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("用户不存在: %s", result.Error),
		})
		return
	}
	if !utils.ValidPassword(password, user.Slat, user.Password) {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("密码错误"),
		})
		return
	}

	user.Identity = utils.Md5(fmt.Sprintf("id:%d", time.Now().Unix()))
	ctx.JSON(200, gin.H{
		"code": 1,
		"msg":  "登陆成功",
		"data": user,
	})
}

// CreateUser
// @Summary 新增用户
// @Tags 用户模块
// @Param name formData string false "name"
// @Param password formData string false "password"
// @Success 200 {string} json{"code", "msg", "data"}
// @Router /user [post]
func CreateUser(ctx *gin.Context) {
	user := models.UserBasic{}
	name := ctx.PostForm("name")
	password := ctx.PostForm("password")

	utils.DB.Where("name = ?", name).First(&user)
	if user.Name != "" {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("用户已注册"),
		})
		return
	}
	slat := fmt.Sprintf("%06d", rand.Int32())
	mkpass := utils.MakePassword(password, slat)
	user.Password = mkpass
	user.Name = name
	user.Slat = slat
	result := utils.DB.Create(&user)
	if result.Error != nil {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("创建用户失败: %s", result.Error),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code": 1,
		"data": "创建用户成功",
	})
}

// DeleteUser
// @Summary 删除用户
// @Tags 用户模块
// @Param id path int true "id"
// @Success 200 {string} json{"code", "msg", "data"}
// @Router /user/{id} [delete]
func DeleteUser(ctx *gin.Context) {
	user := models.UserBasic{}
	id, _ := strconv.Atoi(ctx.Param("id"))
	user.ID = uint(id)
	// user.ID = 0
	fmt.Println(ctx.Param("id"))
	fmt.Println(&user)
	result := utils.DB.Delete(&user)
	if result.Error != nil {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("删除用户失败: %s", result.Error),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code": 1,
		"msg":  "删除用户成功",
	})
}

// UpdateUser
// @Summary 修改用户
// @Tags 用户模块
// @Param id path int true "id"
// @Param name formData string false "name"
// @Param password formData string false "password"
// @Param phone formData string false "phone"
// @Param email formData string false "email"
// @Success 200 {string} json{"code", "msg", "data"}
// @Router /user/{id} [put]
func UpdateUser(ctx *gin.Context) {
	user := models.UserBasic{}
	id, _ := strconv.Atoi(ctx.Param("id"))
	user.ID = uint(id)
	user.Name = ctx.PostForm("name")
	user.Password = ctx.PostForm("password")
	user.Phone = ctx.PostForm("phone")
	user.Email = ctx.PostForm("email")
	fmt.Println(&user)
	valid, err := govalidator.ValidateStruct(user)
	fmt.Println(valid, err)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("修改用户失败: %s", err),
		})
		return
	}
	result := utils.DB.Model(&user).Updates(models.UserBasic{Name: user.Name, Password: user.Password, Phone: user.Phone, Email: user.Email})
	// result := utils.DB.Save(&user)
	if result.Error != nil {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("修改用户失败: %s", result.Error),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code": 1,
		"msg":  "修改用户成功",
	})
}

// UpdateUser
// @UserMe 当前用户
// @Tags 用户模块
// @Param id query int true "User ID"
// @Success 200 {string} json{"code", "msg", "data"}
// @Router /user/me [get]
func UserMe(ctx *gin.Context) {
	user := models.UserBasic{}
	idParam := ctx.Query("id")
	id, _ := strconv.Atoi(idParam)
	user.ID = uint(id)
	key := fmt.Sprintf("user:%s", idParam)

	err := utils.CacheGet(key, &user)
	if err == nil {
		fmt.Println(user)
		ctx.JSON(200, gin.H{
			"code": 1,
			"data": user,
		})
		return
	}
	result := utils.DB.First(&user)
	if result.Error != nil {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("查找用户失败: %s", result.Error),
		})
		return
	}
	err = utils.CacheSet(key, user)
	if err != nil {
		ctx.JSON(200, gin.H{
			"code": -1,
			"msg":  fmt.Sprintf("lmdb写入异常: %s", err),
		})
		return
	}
	ctx.JSON(200, gin.H{
		"code": 1,
		"data": user,
	})
}

var upGrade = websocket.Upgrader{
	CheckOrigin: func(req *http.Request) bool {
		return true
	},
}

func SendMsg(ctx *gin.Context) {
	ws, err := upGrade.Upgrade(ctx.Writer, ctx.Request, nil)
	if err != nil {
		fmt.Println(err)
	}
	defer func(ws *websocket.Conn) {
		err := ws.Close()
		if err != nil {
			fmt.Println(err)
		}
	}(ws)
	utils.CacheSet("WEBSOCKET", []byte("test"))
	var msg string
	utils.CacheGet("WEBSOCKET", &msg)
	msg = utils.Base64Decode(msg)
	err = ws.WriteMessage(1, []byte(fmt.Sprintf("[ws][%s]:%s", time.Now().Format("2006-01-02 15:05:05"), msg)))
	if err != nil {
		fmt.Println(err)
	}
}
